/*
 * 〈描述〉
 *
 * @author chenxing
 * @since 版本号
 */

package com.maorioi.failureanalyzer.component;

import com.google.gson.Gson;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 〈一句话功能简述〉
 *
 * <p>〈功能详细描述〉
 *
 * @author chenxing
 * @since 版本号
 */
@Component
@ConditionalOnProperty(name = "zz.enable-failure-notify", havingValue = "true")
@ConditionalOnResource(resources = {"classpath:build-info.properties"})
@PropertySource(value = "classpath:build-info.properties")
@ConfigurationProperties("build-info")
public class StartupFailureNotifier implements ApplicationListener<ApplicationFailedEvent> {

    private String dateTime;
    private String gitBranch;
    private String envName;

    public void onApplicationEvent(ApplicationFailedEvent applicationFailedEvent) {
        Throwable throwable = applicationFailedEvent.getException();
        int limit = 10;
        StringBuilder stringBuilder = new StringBuilder();
        while (throwable.getCause() != null && limit-- > 0) {
            appendThrowable(stringBuilder, throwable);
            throwable = throwable.getCause();
        }
        appendThrowable(stringBuilder, throwable);
        Map data = new HashMap();
        data.put("envName", this.envName);
        data.put("gitBranch", this.gitBranch);
        data.put("buildTime", this.dateTime);
        data.put("message", stringBuilder.toString());
        Gson gson = new Gson();
        System.out.println(gson.toJson(data));
    }

    private void appendThrowable(StringBuilder stringBuilder, Throwable throwable) {
        boolean putDots = false;
        stringBuilder.append("Caused by: ").append(throwable.getClass()).append(throwable.getMessage()).append("\n");
        for (StackTraceElement stackTraceElement : throwable.getStackTrace()) {
            String st = stackTraceElement.toString();
            if (st.startsWith("com.epoch.") || st.startsWith("com.yuanian.")) {
                if (putDots) {
                    stringBuilder.append("...\n");
                    putDots = false;
                }
                stringBuilder.append("  at ").append(stackTraceElement).append("\n");
            } else {
                putDots = true;
            }
        }
        if (putDots) {
            stringBuilder.append("...\n");
        }
    }

    public String getDateTime() {
        return dateTime;
    }

    public void setDateTime(String dateTime) {
        this.dateTime = dateTime;
    }

    public String getGitBranch() {
        return gitBranch;
    }

    public void setGitBranch(String gitBranch) {
        this.gitBranch = gitBranch;
    }

    public String getEnvName() {
        return envName;
    }

    public void setEnvName(String envName) {
        this.envName = envName;
    }
}
